from khronos.opt.base.solver import Solver
from khronos.statistics import TSeries

class PathBasedSolver(Solver):
    def init(self, *args, **kwargs):
        Solver.init(self, *args, **kwargs)
        self.path_tseries = TSeries(numeric=True, storing=True)
        
    def run(self, *args, **kwargs):
        for _ in self.recorded_path(*args, **kwargs):
            pass
        return self.solutions.best()
        
    def path(self, *args, **kwargs):
        """This method should return an iterable describing the path of the solver."""
        raise NotImplementedError()
        
    def recorded_path(self, *args, **kwargs):
        """This method simply calls the path() method with the provided arguments, but records the 
        objective function value and cpu time of each solution given by path into the solver's 
        TSeries object."""
        for solution in self.path(*args, **kwargs):
            self.path_tseries.collect(self.objective(solution), self.cpu.total)
            yield solution
            
    def plot_path(self):
        axes = self.path_tseries.run_chart(color="blue", linewidth=1.5, linestyle="solid")
        self.path_tseries.derive(TSeries.min).run_chart(target=axes, color="red", 
                                                        linewidth=2, linestyle="dashed")
        axes.set_xlabel("CPU (s)")
        axes.set_ylabel("Objective")
        axes.figure.plotter.update()
        return axes
        